package com.jarvis.plugin.wxmock.plugin;

import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf;
import static net.bytebuddy.matcher.ElementMatchers.named;

import com.jarvis.core.interceptor.InstanceMethodsInterceptor;
import com.jarvis.core.interceptor.Interceptor;
import com.jarvis.core.plugin.AbstractPluginDefine;
import com.jarvis.plugin.wxmock.interceptor.HttpclientInterceptor;
import com.jarvis.plugin.wxmock.interceptor.OkhttpInterceptor;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import okhttp3.Request;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.impl.client.CloseableHttpClient;

/**
 * @author xuxukang
 * @create 2020/5/9 5:55 下午
 */
public class HttpWxmockPlugin extends AbstractPluginDefine {

  private static final String PLUGIN_NAME = "http_wxmock_plugin";

  @Override
  public Interceptor[] interceptors() {
    return new Interceptor[]{
        // okhttp请求创建拦截器
        new InstanceMethodsInterceptor() {
          @Override
          public ElementMatcher<MethodDescription> methodMatcher() {
            return named("newCall").and(ElementMatchers.takesArgument(0, Request.class));
          }

          @Override
          public Class<?> getInterceptClass() {
            return OkhttpInterceptor.class;
          }
        },

        // httpclient请求执行拦截器
        new InstanceMethodsInterceptor() {
          @Override
          public ElementMatcher<MethodDescription> methodMatcher() {
            return named("doExecute").and(ElementMatchers.returns(CloseableHttpResponse.class));
          }

          @Override
          public Class<?> getInterceptClass() {
            return HttpclientInterceptor.class;
          }
        }
    };
  }

  @Override
  public ElementMatcher<? super TypeDescription> typeMatcher() {
    return isSubTypeOf(CloseableHttpClient.class)
        .or(isPublic().and(named("okhttp3.OkHttpClient")));
  }

  @Override
  public String pluginName() {
    return PLUGIN_NAME;
  }
}
